package com.ruoyi.ruoyixingyue.modules.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.ConvertUtils;
import com.ruoyi.common.core.utils.page.PageData;
import com.ruoyi.ruoyixingyue.modules.api.entity.*;
import com.ruoyi.ruoyixingyue.modules.api.mapper.CourseCatalogueMapper;
import com.ruoyi.ruoyixingyue.modules.api.po.CatalogueDetailPo;
import com.ruoyi.ruoyixingyue.modules.api.po.CataloguePidPo;
import com.ruoyi.ruoyixingyue.modules.api.po.CourseCatalogueDictPo;
import com.ruoyi.ruoyixingyue.modules.api.po.CourseCatalogueListPo;
import com.ruoyi.ruoyixingyue.modules.api.service.*;
import com.ruoyi.ruoyixingyue.modules.api.vo.CatagueInsertVo;
import com.ruoyi.ruoyixingyue.modules.api.vo.CourseCatalogueListVo;
import com.ruoyi.ruoyixingyue.modules.utils.Condition;
import com.ruoyi.ruoyixingyue.modules.utils.QueryPage;
import com.ruoyi.ruoyixingyue.modules.utils.TreeUtils;
import com.ruoyi.ruoyixingyue.modules.utils.ValidatorUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 章节表 服务实现类
 * </p>
 *
 * @author lzz
 * @since 2024-02-24
 */
@Service
public class CourseCatalogueServiceImpl extends ServiceImpl<CourseCatalogueMapper, CourseCatalogue> implements ICourseCatalogueService {

    @Autowired
    private ITeacherService teacherService;

    @Autowired
    private ICourseService courseService;

    @Autowired
    private ICourseTypeService courseTypeService;

    @Autowired
        private IMediaService mediaService;

    @Autowired
    private IFileService fileService;


    @Override
    public R<PageData<CourseCatalogueListPo>> courseCatalogueListAPI_001(Condition<CourseCatalogueListVo> condition) {
        CourseCatalogueListVo catalogueListVo = condition.getCondition();
        Long teacherId = catalogueListVo.getTeacherId();
        QueryPage queryPage = condition.getPage();
        Page<CourseCatalogue> cataloguePage = new Page<CourseCatalogue>().setCurrent(queryPage.getCurrent()).setSize(queryPage.getSize());
        QueryWrapper<CourseCatalogue> queryWrapper = new QueryWrapper<>();
        // 进行查询
        //region 教师的查询条件
        List<Long> courseIdList = new ArrayList<>();
        if (Objects.nonNull(teacherId)) {
            List<Course> courseList = courseService.list(new QueryWrapper<Course>().lambda().eq(Course::getTeacherId, teacherId));
            courseIdList = courseList.stream().map(Course::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(courseIdList)) {
                return R.ok(new PageData<>(new ArrayList<>(), 0L));
            }
        }
        //endregion
        List<Long> courseTypeIdList = new ArrayList<>();
        if (Objects.nonNull(catalogueListVo.getTypeId())) {
            List<Course> courseList = courseService.list(new QueryWrapper<Course>().lambda().eq(Course::getTypeId, catalogueListVo.getTypeId()));
            courseTypeIdList = courseList.stream().map(Course::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(courseTypeIdList)) {
                return R.ok(new PageData<>(new ArrayList<>(), 0L));
            }
        }

        queryWrapper.lambda()
                .orderByDesc(CourseCatalogue::getCreateTime)
                .in(!CollectionUtils.isEmpty(courseIdList), CourseCatalogue::getCourseId, courseIdList)
                .in(!CollectionUtils.isEmpty(courseTypeIdList), CourseCatalogue::getCourseId, courseTypeIdList)
                .eq(Objects.nonNull(catalogueListVo.getCourseId()), CourseCatalogue::getCourseId, catalogueListVo.getCourseId())
                .eq(Objects.nonNull(catalogueListVo.getType()), CourseCatalogue::getType, catalogueListVo.getType());

        if (!CollectionUtils.isEmpty(catalogueListVo.getIdList())) {
            queryWrapper.lambda()
                    .in(CourseCatalogue::getId, catalogueListVo.getIdList());
        }

        if (!CollectionUtils.isEmpty(catalogueListVo.getCreateTimeList())) {
            queryWrapper.lambda()
                    .ge(!CollectionUtils.isEmpty(catalogueListVo.getCreateTimeList()), CourseCatalogue::getCreateTime, catalogueListVo.getCreateTimeList().get(0))
                    .le(!CollectionUtils.isEmpty(catalogueListVo.getCreateTimeList()), CourseCatalogue::getCreateTime, catalogueListVo.getCreateTimeList().get(1));
        }
        // 构建查询结果
        this.page(cataloguePage, queryWrapper);
        List<CourseCatalogue> records = cataloguePage.getRecords();

        if (CollectionUtils.isEmpty(records)) {
            return R.ok(new PageData<>(new ArrayList<>(), 0L));
        }
        ArrayList<CourseCatalogueListPo> resultList = new ArrayList<>();

        // 构建返回值需要的map
        Set<Long> parentIdSet = records.stream().map(CourseCatalogue::getPid).collect(Collectors.toSet());
        List<CourseCatalogue> catalogueList = !CollectionUtils.isEmpty(parentIdSet) ? this.list(new QueryWrapper<CourseCatalogue>().lambda().in(CourseCatalogue::getId, parentIdSet)) : new ArrayList<CourseCatalogue>();
        Map<Long, CourseCatalogue> catalogueMap = catalogueList.stream().collect(Collectors.toMap(CourseCatalogue::getId, courseCatalogue -> courseCatalogue, (next, prex) -> prex));

        List<Long> queryCourseIdList = records.stream().map(CourseCatalogue::getCourseId).collect(Collectors.toList());
        List<Course> queryCourseList = courseService.list(new QueryWrapper<Course>().lambda().in(!CollectionUtils.isEmpty(queryCourseIdList), Course::getId, queryCourseIdList));
        Set<Long> courseTypeIdSet = queryCourseList.stream().map(Course::getTypeId).collect(Collectors.toSet());

        Map<Long, Course> queryGetTeacherIdMap = queryCourseList.stream().collect(Collectors.toMap(Course::getId, course -> course));
        List<CourseType> courseTypeList = courseTypeService.listByIds(courseTypeIdSet);
        Map<Long, CourseType> courseTypeMap = courseTypeList.stream().collect(Collectors.toMap(CourseType::getId, courseType -> courseType));

        List<Long> teacherIdList = queryCourseList.stream().map(Course::getTeacherId).collect(Collectors.toList());
        List<Teacher> teacherList = teacherService.listByIds(teacherIdList);
        Map<Long, Teacher> teacherMap = teacherList.stream().collect(Collectors.toMap(Teacher::getId, teacher -> teacher, (prex, next) -> next));

        records.forEach(courseCatalogue -> {
            CourseCatalogueListPo target = ConvertUtils.sourceToTarget(courseCatalogue, CourseCatalogueListPo.class);
            Optional.ofNullable(catalogueMap.get(courseCatalogue.getPid())).ifPresent(courseCatalogue1 -> {
                target.setParentName(courseCatalogue1.getName());
            });
            Optional.ofNullable(queryGetTeacherIdMap.get(courseCatalogue.getCourseId())).ifPresent(course -> {
                target.setCourseName(course.getName());
                Optional.ofNullable(courseTypeMap.get(course.getTypeId())).ifPresent(courseType -> {
                    target.setCourseType(courseType.getName());
                });
                Optional.ofNullable(teacherMap.get(course.getTeacherId())).ifPresent(teacher -> {
                    target.setTeacherName(teacher.getUserName());
                });
            });
            resultList.add(target);
        });

        return R.ok(new PageData<>(resultList, cataloguePage.getTotal()));
    }

    /**
     * 课程目录字典
     */
    @Override
    public R<List> courseCatalogueDictAPI_002() {
        List<CourseCatalogue> courseCatalogueList = this.list(new QueryWrapper<CourseCatalogue>());
        List<CourseCatalogueDictPo> resultList = ConvertUtils.sourceToTarget(courseCatalogueList, CourseCatalogueDictPo.class);
        List<CourseCatalogueDictPo> treeList = TreeUtils.build(resultList);
        return R.ok(treeList, "构建树结构");
    }

    /**
     * 所属章节字典
     */
    @Override
    public R<List> PidDictAPI_003(Long courseId) {
        List<CourseCatalogue> catalogueList = this.list(new QueryWrapper<CourseCatalogue>().lambda()
                .eq(CourseCatalogue::getCourseId, courseId)
                .eq(CourseCatalogue::getPid, 0L));
        List<CataloguePidPo> resultList = ConvertUtils.sourceToTarget(catalogueList, CataloguePidPo.class);
        return R.ok(resultList, "获取数据成功");
    }

    /** 新增章节*/
    @Override
    @Transactional
    public R<String> catagueInsertAPI_004(CatagueInsertVo catagueInsertVo) {
        ValidatorUtils.validateEntity(catagueInsertVo);
        CourseCatalogue courseCatalogue = ConvertUtils.sourceToTarget(catagueInsertVo, CourseCatalogue.class);
        if (Objects.isNull(catagueInsertVo.getPid())) {
            courseCatalogue.setPid(0L);
        }
        courseCatalogue.setCIndex(catagueInsertVo.getIndex());
        this.save(courseCatalogue);
        Media media = mediaService.getById(courseCatalogue.getMediaId());
        media.setCoverUrl(catagueInsertVo.getCoverUrl());
        mediaService.updateById(media);
        return R.ok(null,"新增成功");
    }

    /** 删除章节以及视频表中的内容*/
    @Override
    @Transactional
    public R<String> catagueDeleteAPI_005(Long id) {
        CourseCatalogue courseCatalogue = this.getById(id);
        Long mediaId = courseCatalogue.getMediaId();
        Media media = mediaService.getById(mediaId);
        String coverUrl = media.getCoverUrl();
        List<File> fileList = fileService.list(new QueryWrapper<File>().lambda().eq(File::getUrl, coverUrl));
        if (!CollectionUtils.isEmpty(fileList)) {
            File file = fileList.get(0);
            fileService.removeById(file);
        }
        mediaService.removeById(media);
        this.removeById(courseCatalogue);
        return R.ok(null,"删除成功");
    }

    /** 根据id得到章节信息*/
    @Override
    public R<CatalogueDetailPo> cataguegetByIdAPI_006(Long id) {
        CourseCatalogue courseCatalogue = this.getById(id);
        CatalogueDetailPo catalogueDetailPo = ConvertUtils.sourceToTarget(courseCatalogue, CatalogueDetailPo.class);
        catalogueDetailPo.setIndex(courseCatalogue.getCIndex());
        Long mediaId = courseCatalogue.getMediaId();
        List<Media> mediaList = mediaService.list(new QueryWrapper<Media>().lambda().eq(Media::getId, mediaId));
        if (!CollectionUtils.isEmpty(mediaList)) {
            Media media = mediaList.get(0);
            catalogueDetailPo.setMediaUrl(media.getMediaUrl());
            catalogueDetailPo.setCoverUrl(media.getCoverUrl());
        }
        return R.ok(catalogueDetailPo,"获取信息成功");
    }
}
